package com.apestech.framework.run.core;

import com.apestech.framework.db.SqlSession;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.run.datamapper.MappingData;
import com.apestech.framework.run.datamapper.SingleDataMappingModule;
import com.apestech.framework.run.modul.ExecListParam;
import com.apestech.framework.run.modul.ExecSingleParam;
import com.apestech.framework.util.ExceptionUtil;
import com.apestech.framework.util.ReflectUtil;
import com.apestech.framework.util.StringFuncUtil;

import java.util.ArrayList;

/**
 * 数据关联的过程执行</br>
 * 入参和出参均要求为MAP格式</br>
 *
 * @author hupo * @create 2018-03-15-17:32
 */
public class ProcessExecution extends StringFuncUtil{

    private JSONObject data=null;
    private JSONObject outParam=null;
    private SqlSession session=null;

    public void setSqlSession(SqlSession session){
        this.session=session;
    }

    public void execution(ExecListParam listParam, JSONObject inParam) throws Exception{
        if(inParam!=null){
            this.data=new JSONObject(inParam);
        } else{
            this.data=new JSONObject();
        }
        int len=listParam.size();
        JSONObject in=new JSONObject();
        for(int i=0; i<len; i++){
            JSONObject zin=getInput(listParam.get(i));
            if(zin!=null){
                this.data.putAll(zin);
            }
            JSONObject r=execProcess(listParam.get(i), zin);
            if(r!=null){
                this.data.putAll(r);
            }
            if(i==len-1){
                getOutpug(listParam.get(i).getOutput(), listParam.get(i).hasOutput());
            }
        }
    }

    private JSONObject getInput(ExecSingleParam param) throws Exception {
        return getMapper(param.getInput());
    }

    private JSONObject getOutpug(Object output, boolean hasOutput) throws Exception {
       return getOutpugMap(output, hasOutput);
    }

    private JSONObject getOutpugMap(Object output, boolean hasOutput) throws Exception {
        if(output!=null){
            if("all".equals(output)){
                this.outParam=this.data;
            } else {
                if(hasOutput) {
                    this.outParam = getMapper(output);
                }
            }
        }
        return this.outParam;
    }

    private JSONObject execProcess(ExecSingleParam param, JSONObject input) throws Exception {
        String type=param.getType();
        JSONObject result=null;
        switch(type){
            case "method":
                String className=param.getClassName();
                String methodName=param.getMethodName();
                Object obj= ReflectUtil.getObject(className);
                if(input==null){
                    result=(JSONObject)ReflectUtil.execMethod(obj, methodName);
                } else {
                    result=(JSONObject)ReflectUtil.execMethod(obj, methodName, input);
                }
                break;
            case "query":
                if(this.session==null){
                    ExceptionUtil.exception(this,"execProcess","查询方式执行必需获取session！");
                }
                //result=this.session.queryByIdToJson(param.getQueryId(), input);
                break;
            case "pricingProcess":
                if(input==null){
                    ExceptionUtil.exception(this,"execProcess","定价过程入参必填！");
                }
                if(this.session==null){
                    ExceptionUtil.exception(this,"execProcess","定价过程必需获取session！");
                }
                //result=this.session.pricingProcess(input);
                break;
            case "json":
                //静态类调用
                result=null;
                break;
            case "ruleEngine":
                //静态类调用
                result=(JSONObject)param.getInput();
                break;
            case "condition":
                if(input==null){
                    ExceptionUtil.exception(this,"execProcess","条件类型入参必填！");
                }
                if(this.session==null){
                    ExceptionUtil.exception(this,"execProcess","条件类型必需获取session！");
                }
                //result=this.session.pricingProcess(input);
                break;
            case "http":
                //静态类调用
                result=null;
                break;
        }
        return result;
    }

    private JSONObject getMapper(Object param) throws Exception{
        if(param==null) return null;
        if (param instanceof JSONObject) {
            return (JSONObject) param;
        } else if (param instanceof ArrayList) {
            return getMapper((ArrayList<SingleDataMappingModule>) param);
        } else if (param instanceof String) {
            return getMapper((String) param);
        }
        return null;
    }

    private JSONObject getMapper(String text) throws Exception{
        MappingData dm=new MappingData();
        dm.add(text);
        return dm.getData(this.data);
    }

    private JSONObject getMapper(ArrayList<SingleDataMappingModule> param) throws Exception{
        MappingData dm=new MappingData();
        dm.setParams(param);
        return dm.getData(this.data);
    }

    public JSONObject getOutParam(){
        return this.outParam;
    }


}
